from typing import Optional, final

from server.apps.blog.infrastructure import forms
from server.apps.blog.logic.posts import commands
from server.apps.blog.models import Post


@final
class Failed(Exception):
    """
    This is a domain error.

    It means, that we are not able to rate this post.
    Details are stored in the ``.context`` property.
    """

    def __init__(self, form: forms.FriendlyPostForm) -> None:
        super().__init__()
        self.context = {'form': form}


def run(
    form: forms.FriendlyPostForm,
) -> Optional[Post]:
    """Validates data, maybe creates a new post, returns all published ones."""
    validated_data = form.get_valid_data()
    if validated_data is None:
        raise Failed(form)
    return commands.create(validated_data)
